﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Colorful.Caching;
using Microsoft.Extensions.Options;
using Senparc.Weixin;
using Senparc.Weixin.Entities;
using Senparc.Weixin.MP.CommonAPIs;
using Volo.Abp;

namespace Colorful.Furniture.MpManagement;

/// <summary>
///  微信公众号拓展
/// </summary>
public class SenparcWechatMpExtensions : IWechatMpExtensions
{
    private readonly IRedisCache _redisCache;
    private readonly WechatMpOptions _wechatMpOptions;

    public SenparcWechatMpExtensions(
        IRedisCache redisCache,
        IOptions<WechatMpOptions> wechatMpOptions)
    {
        _redisCache = redisCache;
        _wechatMpOptions = wechatMpOptions.Value;
    }

    /// <summary>
    ///  异步获取令牌
    /// </summary>
    /// <returns></returns>
    /// <exception cref="System.NotImplementedException"></exception>
    public async Task<string> GetAccessTokenAsync()
    {
        return await GetAccessTokenAsync(_wechatMpOptions.AppId, _wechatMpOptions.AppSecret);
    }

    /// <summary>
    ///  异步获取令牌
    /// </summary>
    /// <param name="appId"></param>
    /// <param name="appSecret"></param>
    /// <returns></returns>
    public async Task<string> GetAccessTokenAsync(string appId, string appSecret)
    {
        if (string.IsNullOrWhiteSpace(appId))
            throw new ArgumentNullException(nameof(appId));

        if (string.IsNullOrWhiteSpace(appSecret))
            throw new ArgumentNullException(nameof(appSecret));

        var accessTokenKey = $"Colorful.Furniture.Mp.AccessToken:{_wechatMpOptions.AppId}";

        //从Redis中获取accessToken
        var accessTokenCache = await _redisCache.GetAsync<string>(accessTokenKey);

        if (!string.IsNullOrWhiteSpace(accessTokenCache)) return accessTokenCache;

        var result = await CommonApi.GetTokenAsync(appId, appSecret);

        HandleWxJsonResult(result);

        await _redisCache.SetAsync(accessTokenKey, result.access_token, result.expires_in);

        return result.access_token;
    }

    /// <summary>
    ///  微信JSON结果
    /// </summary>
    /// <param name="wxJsonResultResponse"></param>
    public void HandleWxJsonResult<T>(T wxJsonResultResponse)
    {
        var wxJsonResult = wxJsonResultResponse as WxJsonResult;

        if (wxJsonResult == null)
            throw new UserFriendlyException($"未能转换微信响应对象{nameof(wxJsonResultResponse)}");

        var returnCodeDictionary = new Dictionary<int, string>
        {
            {40163, "code已被使用"}
        };

        if (returnCodeDictionary.ContainsKey(wxJsonResult.ErrorCodeValue))
            throw new UserFriendlyException(returnCodeDictionary[wxJsonResult.ErrorCodeValue],wxJsonResult.ErrorCodeValue.ToString());

        if (wxJsonResult.errcode != ReturnCode.请求成功)
            throw new UserFriendlyException($"{wxJsonResult.errcode}",wxJsonResult.ErrorCodeValue.ToString());
    }
}